Shader "Post-Processing/NPR Postprocess"
{
    HLSLINCLUDE
    #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"

    float2 _BlitTexture_TexelSize;
    half _BloomThreshold;
    half _BloomIntensity;
    half _BlurRadius;


    TEXTURE2D(_BloomTextureA);
    TEXTURE2D(_BloomTextureB);
    TEXTURE2D(_BloomTextureC);
    TEXTURE2D(_BloomTextureD);
    
    // 高斯模糊
    half4 GaussianBlur(float2 uv, float2 direction)
    {
        float2 offset = _BlurRadius * _BlitTexture_TexelSize * direction;

        half4 color = 0.0;
        color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv -4 * offset) * 0.01621622;
        color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv -3 * offset) * 0.05405405;
        color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv -2 * offset) * 0.12162162;
        color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv -1 * offset) * 0.19459459;
        color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + 0 * offset) * 0.22702703;
        color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + 1 * offset) * 0.19459459;
        color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + 2 * offset) * 0.12162162;
        color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + 3 * offset) * 0.05405405;
        color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + 4 * offset) * 0.01621622;

        return color;
    }
    
    
    half4 Prefilter(Varyings input) : SV_TARGET
    {
        float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
        half4 color = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);
        color.rgb = max(color.rgb - _BloomThreshold, 0.0);

        return color;
    }
    
    half4 HorizontalBlur1x(Varyings input) : SV_TARGET
    {
        float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
        return GaussianBlur(uv, float2(1.0, 0.0));
    }

    half4 HorizontalBlur2x(Varyings input) : SV_TARGET
    {
        float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
        return GaussianBlur(uv, float2(2.0, 0.0));
    }

    half4 VerticalBlur1x(Varyings input) : SV_TARGET
    {
        float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
        return GaussianBlur(uv, float2(0.0, 1.0));
    }

    half4 VerticalBlur2x(Varyings input) : SV_TARGET
    {
        float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
        return GaussianBlur(uv, float2(0.0, 2.0));
    }

    half4 UpSample(Varyings input) : SV_TARGET
    {
        float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);

        half4 color = 0.0h;
        color += SAMPLE_TEXTURE2D_X(_BloomTextureA, sampler_LinearClamp, uv);
        color += SAMPLE_TEXTURE2D_X(_BloomTextureB, sampler_LinearClamp, uv);
        color += SAMPLE_TEXTURE2D_X(_BloomTextureC, sampler_LinearClamp, uv);
        color += SAMPLE_TEXTURE2D_X(_BloomTextureD, sampler_LinearClamp, uv);

        return color * 0.25h;
    }


    half4 ColorBlend(Varyings input) : SV_TARGET
    {
        float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
        half4 color = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);

        half3 bloom = SAMPLE_TEXTURE2D_X(_BloomTextureA, sampler_LinearClamp, uv).rgb;
        bloom *= _BloomIntensity;
        color.rgb += bloom;

        return color;
    }
    ENDHLSL

    Subshader
    {
        Pass
        {
            Name "Prefilter"

            HLSLPROGRAM
            #pragma vertex Vert
            #pragma fragment Prefilter
            ENDHLSL
        }

        Pass
        {
            Name "HorizontalBlur1x"

            HLSLPROGRAM
            #pragma vertex Vert
            #pragma fragment HorizontalBlur1x
            ENDHLSL
        }

        Pass
        {
            Name "HorizontalBlur2x"

            HLSLPROGRAM
            #pragma vertex Vert
            #pragma fragment HorizontalBlur2x
            ENDHLSL
        }

        Pass
        {
            Name "VerticalBlur1x"

            HLSLPROGRAM
            #pragma vertex Vert
            #pragma fragment VerticalBlur1x
            ENDHLSL
        }

        Pass
        {
            Name "VerticalBlur2x"

            HLSLPROGRAM
            #pragma vertex Vert
            #pragma fragment VerticalBlur2x
            ENDHLSL
        }

        Pass
        {
            Name "UpSample"

            HLSLPROGRAM
            #pragma vertex Vert
            #pragma fragment UpSample
            ENDHLSL
        }

        Pass
        {
            Name "ColorBlend"

            HLSLPROGRAM
            #pragma vertex Vert
            #pragma fragment ColorBlend
            ENDHLSL
        }
    }
}